﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ParallelRuntimeLibrary;
using ParallelRuntimeLibrary.Collections;
using System.Diagnostics;
using System.Threading;

namespace TestProject
{
    class Program
    {
        static void aa(ref int int1, int int2) { int1 += int2; }
        static void Main(string[] args)
        {// Test

            CountdownEventTest.LoopTest();
            return;

            
        Start:
            int count = 0;

            Action<object> SmallTask = new Action<object>(o =>
                {
                    Interlocked.Increment(ref count);
                    Thread.Sleep(10);
                    int i = (int)o;
                    float p = i * i;
                    p = p / 321.9f + 4.93f * 2;
                    p = 32.12f + 4 * 2;
                    p = 2 + 4 * 2.232f;
                    p = 2 + 4 * 2.232f;
                    Thread.Sleep(10);

                    Action<object> s = new Action<object>(po =>
                    {
                        Interlocked.Increment(ref count);
                        Thread.Sleep(1);
                        p = 2 + 4 * 2.232f;
                        float poe = p + (float)Math.Pow(23.532, (float)p);
                        poe = p + (float)Math.Pow(23.5312, (float)p);
                        poe = p + (float)Math.Pow(2.2, (float)p);
                        poe = p + (float)Math.Pow(2.532, (float)p);
                    });

                    Task[] ts = new Task[41];
                    for (int c = 0; c < ts.Length; c++)
                        ts[c] = new Task(s);

                    TaskManager.WaitAll(ts);

                    p = 2 + 4 * 2.232f;
                    p = 2 + i * 2.232f;
                    p = i + 4 * 2.232f;
                    i *= 8;
                    p = 2 + i * 2.232f;
                    

                });

            Task[] tasks = new Task[6];
            for (int i = 0; i < tasks.Length; i++)
                tasks[i] = new Task(SmallTask, i);


            long z1 = DateTime.UtcNow.Ticks;

            TaskManager.WaitAll(tasks);
            //TaskManager.WaitAll(tasks);

            long z2 = DateTime.UtcNow.Ticks - z1;

            Console.WriteLine((count == 252).ToString() + "\t" + z2);
            Console.WriteLine(count);
            Console.ReadLine();
            goto Start;
            return;


            //// end

            //ThreadPool.SetMinThreads(4, 4);

            ParallelRuntimeLibrary.Collections.Combinable<List<int>> alpha = new ParallelRuntimeLibrary.Collections.Combinable<List<int>>();

            DateTime d1 = DateTime.Now;
            int counter = 0;

            ParallelRuntimeLibrary.HPDispatcher.Parallel.For(0, 99999999, ThreadPriority.Normal, () => alpha.Local, (i,xx) =>
                {
                    float pos = 342342.343f;
                    pos = (float)Math.Sqrt(pos / 43) + (float)Math.Sqrt(pos);
                    pos = (float)Math.Sqrt(pos + 43) + (float)Math.Sqrt(pos * 72);
                    pos = (float)Math.Sqrt(pos / 0.23) + (float)Math.Sqrt(pos / 21);
                    xx.Add(0);
                });

            var ss = alpha.Combine((result, temp) => result.AddRange(temp));

            TimeSpan d2 = DateTime.Now - d1;
            Console.WriteLine(d2.TotalMilliseconds);
            Console.WriteLine("Counter value : " + ss.Count);
            return;


            for (int i = 1; i < 56; i+=22)
            {
                Console.WriteLine(i.ToString());
            }
            Parallel.TestFor(1, 56, 22);
            return;
            Stopwatch SW = new Stopwatch();
            Console.WriteLine("Press any key to start the test");
            Console.ReadLine();

            ConcurrentBagTester.Start();

            //ListTester.Start();
            return;

            SW.Start();

            Task[] X = new Task[8];
            X[0] = new Task(ThreadWork);
            X[1] = new Task(ThreadWork);
            X[2] = new Task(ThreadWork);
            X[3] = new Task(ThreadWork);
            X[4] = new Task(ThreadWork);
            X[5] = new Task(ThreadWork);
            X[6] = new Task(ThreadWork);
            X[7] = new Task(ThreadWork);
            ParallelRuntimeLibrary.TaskManager.WaitAll(X);

            //Task[] X2 = new Task[3];
            //X2[0] = new Task(ThreadWork);
            //X2[1] = new Task(ThreadWork);
            //X2[2] = new Task(ThreadWork);
            //ParallelRuntimeLibrary.TaskManager.WaitAll(X2);

            SW.Stop();

            Console.WriteLine(SW.ElapsedMilliseconds);
            Console.ReadLine();

        }


        static void ThreadWork2(object obj)
        {
            Console.WriteLine("Start Base = " + Thread.CurrentThread.ManagedThreadId);

            Thread.Sleep(555);

            Task[] X2 = new Task[2];
            X2[0] = new Task(ThreadWork3);
            X2[1] = new Task(ThreadWork3);
            ParallelRuntimeLibrary.TaskManager.WaitAll(X2);

            int[] local = new int[7000000];
            for (int i = 0; i < local.Length; i++)
            {
                local[i] = (int)((i * 2) / 6.1) - 33 + (4 * i);
                local[i] = local[i] + local[i] + local[i];
                local[i] = (int)((i * 3) / 0.3) - 33 + (3 * i);
                local[i] = (int)((i * 4) / 1.6) - 33 + (2 * i);
            }
            Console.WriteLine("End Base = " + Thread.CurrentThread.ManagedThreadId); ;
        }

        static void ThreadWork3(object obj)
        {
            Console.WriteLine("Start Very Base = " + Thread.CurrentThread.ManagedThreadId);
            int[] local = new int[5000000];
            for (int i = 0; i < local.Length; i++)
            {
                local[i] = (int)((i * 2) / 6.1) - 33 + (4 * i);
                local[i] = local[i] + local[i] + local[i];
                local[i] = (int)((i * 3) / 0.3) - 33 + (3 * i);
                local[i] = (int)((i * 4) / 1.6) - 33 + (2 * i);
            }
            Console.WriteLine("End VBase = " + Thread.CurrentThread.ManagedThreadId); ;
        }

        static void ThreadWork(object obj)
        {
            Console.WriteLine("Start = " + Thread.CurrentThread.ManagedThreadId);
            int[] local = new int[12000000];
            for (int i = 0; i < local.Length; i++)
            {
                local[i] = (int)((i * 2) / 6.1) - 33 + (4 * i);
                local[i] = local[i] + local[i] + local[i];
                local[i] = (int)((i * 3) / 0.3) - 33 + (3 * i);
                local[i] = (int)((i * 4) / 1.6) - 33 + (2 * i);
            }

            Task[] X2 = new Task[2];
            X2[0] = new Task(ThreadWork2);
            X2[1] = new Task(ThreadWork2);
            ParallelRuntimeLibrary.TaskManager.WaitAll(X2);

            for (int i = 0; i < local.Length; i++)
            {
                local[i] = (int)((i * 10) / 6.1) - 303 + (4 * i);
                local[i] = local[i] / local[i] * local[i];
                local[i] = (int)((i * 5) / 0.3) - 133 + (11 * i);
                local[i] = (int)((i * 7) / 1.6) - 333 + (2 * i);
            }
            Console.WriteLine("End = " + Thread.CurrentThread.ManagedThreadId);
        }


        static void SleepyTaskWork(object obj)
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Start : " + obj);
            Thread.Sleep(1000);
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " end : " + obj);
        }

        static void HeavyTaskWork(object obj)
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Start : " + obj);

            float po = 213.4327f;
            for (int i = 0; i < 40000000; i++)
            {
                po += i;
                po = (float)Math.Sqrt(po / 42) * (float)Math.Sqrt(po);
                po = (float)Math.Sqrt(po) * (float)Math.Sqrt(po * 7);
                po = (float)Math.Sqrt(po * 2) * (float)Math.Sqrt(po);
                po += i;
            }

            Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " end : " + obj);
        }
    }
}
